package com.diorsunion.hedge.client.io.netty;

import com.diorsunion.hedge.common.ServiceResult;
import com.diorsunion.hedge.common.ConnectionStatus;
import com.diorsunion.hedge.io.IOClient;
import com.diorsunion.hedge.io.Message;
import com.diorsunion.hedge.io.netty.NettyChannelInitializer;
import com.diorsunion.hedge.util.LogUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * Created by harley-dog on 2016/5/23.
 */
@Component("NettyClient")
public class NettyClient implements IOClient {
    Channel channel;

    @Override
    public ServiceResult<ConnectionStatus> status() {
        if(channel!=null && channel.isOpen() && channel.isWritable()){
            return ServiceResult.successResult(ConnectionStatus.OK,"已连接上Netty服务端");
        }
        return ServiceResult.successResult(ConnectionStatus.NoOK,"尚未连接上Netty服务端");
    }

    @Resource
    @Qualifier("NettyChannelInitializer")
    NettyChannelInitializer nettyChannelInitializer;

    Bootstrap bootstrap = new Bootstrap();
    @PostConstruct
    public void init(){
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.group(eventLoopGroup);
        bootstrap.handler(nettyChannelInitializer);
    }

    @Override
    public ServiceResult<ConnectionStatus> connect(String address, int port) {
        ServiceResult<ConnectionStatus> connectionStatusServiceResult = status();
        if (connectionStatusServiceResult.obj==ConnectionStatus.OK) {
            return connectionStatusServiceResult;
        }
        ChannelFuture future = null;
        try {
            future = bootstrap.connect(address, port).sync();
        } catch (InterruptedException e) {
            LogUtil.error("netty connected server error, " + address + ":" + port, e);
        }
        if (future != null && future.isSuccess()) {
            channel = future.channel();
            return ServiceResult.successResult(ConnectionStatus.OK,"连接成功");
        }
        return ServiceResult.errorResult(ConnectionStatus.NoOK,"连接失败");
    }


    @Override
    public ServiceResult<ConnectionStatus> disconnect() {

        ServiceResult<ConnectionStatus> connectionStatusServiceResult = status();
        if (connectionStatusServiceResult.obj==ConnectionStatus.NoOK) {
            return connectionStatusServiceResult;
        }
        ChannelFuture future = channel.close();
        if (future != null && future.isSuccess()) {
            channel = future.channel();
            LogUtil.info("netty disconnected");
            return ServiceResult.successResult(ConnectionStatus.NoOK,"断开连接成功");
        }
        return ServiceResult.errorResult(ConnectionStatus.OK,"断开连接失败");
    }

    @Override
    public void write(Message message) {
        if(channel!=null){
            channel.writeAndFlush(message);
        }
    }
}